home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / 32SNIPIT.PAK / UPDTCRNT.C < prev    next >
C/C++ Source or Header  |  1997-05-06  |  14KB  |  395 lines

  1. // BDE32 3.x - (C) Copyright 1996 by Borland International
  2.  
  3. // updtcrnt.c
  4. #include "snipit.h"
  5.  
  6. static pCHAR szTblName = "UPDTCRNT";
  7.  
  8. // Field Descriptor used in creating a table.
  9. static SNIPFAR FLDDesc fldDesc[] =
  10.                         {
  11.                           { // Field 1 - FRSTNAME
  12.                             1,              // Field Number
  13.                             "FRSTNAME",     // Field Name
  14.                             fldZSTRING,     // Field Type
  15.                             fldUNKNOWN,     // Field Subtype
  16.                             10,             // Field Size ( 1 or 0, except
  17.                                             //     BLOb or CHAR field )
  18.                             0,              // Decimal places ( 0 )
  19.                                             //     computed
  20.                             0,              // Offset in record ( 0 )
  21.                             0,              // Length in Bytes  ( 0 )
  22.                             0,              // For Null Bits    ( 0 )
  23.                             fldvNOCHECKS,   // Validiy checks   ( 0 )
  24.                             fldrREADWRITE   // Rights
  25.                           },
  26.                           { // Field 2 - LASTNAME
  27.                             2, "LASTNAME", fldZSTRING, fldUNKNOWN,
  28.                             12, 0, 0, 0, 0,
  29.                             fldvNOCHECKS, fldrREADWRITE
  30.                           }
  31.                        };
  32.  
  33. // Index Descriptor - describes the index associated with the table.
  34. static IDXDesc IdxDesc =
  35.                     {
  36.                         { "UPDTIDX" },      // Name
  37.                         1,                  // Number
  38.                         { NULL },           // Tag name (dBASE only)
  39.                         { NULL },           // Optional format
  40.                         FALSE,              // Primary?
  41.                         TRUE,               // Unique?
  42.                         FALSE,              // Descending?
  43.                         TRUE,               // Maintained?
  44.                         FALSE,              // SubSet?
  45.                         FALSE,              // Expression index?
  46.                         NULL,               // for QBE only
  47.                         2,                  // Fields in key
  48.                         NULL,               // Length in bytes
  49.                         FALSE,              // Index out of date?
  50.                         0,                  // Key Type of Expression
  51.                         { 2, 1 },           // Array of field numbers
  52.                         { NULL },           // Key expression
  53.                         { NULL },           // Key Condition
  54.                         FALSE,              // Case insensitive
  55.                         0,                  // Block size in bytes
  56.                         0                   // Restructure number
  57.                     };
  58.  
  59. // Function prototypes
  60. static DBIResult CreateSQLTable(hDBIDb hDb, pCHAR pszTblName);
  61. static DBIResult AddRecord(hDBICur hCur, pCHAR pFirst, pCHAR pLast);
  62.  
  63. static const UINT16 uNumFields = sizeof(fldDesc) / sizeof (fldDesc[0]);
  64.  
  65. //=====================================================================
  66. //  Function:
  67. //          UpdateCurrent();
  68. //
  69. //  Description:
  70. //          This example shows how to set up a cursor on the server for
  71. //          update. This allows for updating the current record.
  72. //
  73. //          Notes:
  74. //
  75. //              This functionality is only supported by the InterBase 4.0
  76. //              server.
  77. //
  78. //              DbiSetToBegin will not modify the current position of the
  79. //              cursor on the server - the cursor needs to be re-set.
  80. //
  81. //              The 'SQLPASSTHRU MODE' in the InterBase alias used for
  82. //              this example needs to be set to 'SHARED AUTOCOMMIT' for
  83. //              this example to work.
  84. //=====================================================================
  85. void
  86. UpdateCurrent (void)
  87. {
  88.     DBIResult       rslt;       // Return value from IDAPI functions
  89.     hDBIDb          hDb;        // Handle to the database
  90.     hDBICur         hCur;       // Handle to the result set
  91.     hDBICur         hMCur;      // Handle to the table on the server
  92.     hDBIStmt        hStmt;      // Handle to the SQL statement
  93.     hDBIXact        hTran = 0;  // Transaction Handle
  94.     CHAR            szQuery[100] = { // The text of the SQL statement
  95.                 "SELECT *"
  96.                 " FROM UPDTCRNT"
  97.                 " FOR UPDATE OF FRSTNAME"
  98.                                   };
  99.     UINT16          uLength;         // Length of returned property
  100.     CURProps        TblProps;        // Used to determine the size of the
  101.                                      //   Record buffer.
  102.     pBYTE           pRecBuf = NULL;  // Pointer to the record buffer
  103.     BOOL            bBlank;          // Determine if the field is blank
  104.     BYTE            szFirst[20];     // Variable to store the current first name
  105.     BYTE            szNewFirst[]="Bob";      // Name to change to
  106.     CHAR            szDbType[DBIMAXNAMELEN]; // Type of the connection
  107.     CHAR            szCursorName[] = "MyCursor";
  108.  
  109.     Screen("*** Live Answer Table Example ***\r\n");
  110.  
  111.     BREAK_IN_DEBUGGER();
  112.  
  113.     Screen("    Initializing IDAPI...");
  114.     if (InitAndConnect2(&hDb) != DBIERR_NONE)
  115.     {
  116.         Screen("\r\n*** End of Example ***");
  117.         return;
  118.     }
  119.  
  120.     rslt = DbiGetProp(hDb, dbDATABASETYPE, szDbType, sizeof(DBINAME),
  121.                       &uLength);
  122.     ChkRslt(rslt, "GetProp");
  123.  
  124.     // Make certain that the server supports this opperation.
  125.     if (strcmp(szDbType, "INTRBASE"))
  126.     {
  127.         Screen("        Error - 'UPDATE ... WHERE CURRENT OF' is currently"
  128.                " only supported for InterBase v4.0.");
  129.         CloseDbAndExit(&hDb);
  130.         Screen("\r\n*** End of Example ***");
  131.         return;
  132.     }
  133.  
  134.     // Create the table
  135.     if (CreateSQLTable(hDb, szTblName)
  136.         != DBIERR_NONE)
  137.     {
  138.         CloseDbAndExit(&hDb);
  139.         Screen("\r\n*** End of Example ***");
  140.         return;
  141.     }
  142.  
  143.     // Start a transaction to handle the update to the table
  144.     rslt = DbiBeginTran(hDb, xilREADCOMMITTED, &hTran);
  145.     if (ChkRslt(rslt, "BeginTran"))
  146.     {
  147.         CloseDbAndExit(&hDb);
  148.         Screen("\r\n*** End of Example ***");
  149.         return;
  150.     }
  151.  
  152.     Screen("    Perform the following SQL statement on the table:\r\n");
  153.     Screen(szQuery);
  154.  
  155.     // Allocate the statment handle.
  156.     Screen("\r\n    Allocate the statment handle...");
  157.     rslt = DbiQAlloc(hDb, qrylangSQL, &hStmt);
  158.     if (ChkRslt(rslt, "QAlloc") != DBIERR_NONE)
  159.     {
  160.         rslt = DbiEndTran(hDb, hTran, xendABORT);
  161.         ChkRslt(rslt, "EndTran");
  162.         rslt = DbiDeleteTable(hDb, szTblName, NULL);
  163.         ChkRslt(rslt, "DeleteTable");
  164.         CloseDbAndExit(&hDb);
  165.         Screen("\r\n*** End of Example ***");
  166.         return;
  167.     }
  168.     // Prepare the query as a non-live query.
  169.     Screen("\r\n    Prepare the SQL statement...");
  170.     rslt = DbiQPrepare(hStmt, szQuery);
  171.     if (ChkRslt(rslt, "QPrepareExt") != DBIERR_NONE)
  172.     {
  173.         rslt = DbiEndTran(hDb, hTran, xendABORT);
  174.         ChkRslt(rslt, "EndTran");
  175.         rslt = DbiDeleteTable(hDb, szTblName, NULL);
  176.         ChkRslt(rslt, "DeleteTable");
  177.         CloseDbAndExit(&hDb);
  178.         Screen("\r\n*** End of Example ***");
  179.         return;
  180.     }
  181.  
  182.     Screen("    Set the name of the cursor...");
  183.     rslt = DbiSetProp((hDBIObj)hStmt, stmtCURSORNAME, (UINT32)szCursorName);
  184.     ChkRslt(rslt, "SetProp");
  185.  
  186.     Screen("    Force the use of a Uni-Directional cursor...");
  187.     rslt = DbiSetProp((hDBIObj)hStmt, stmtUNIDIRECTIONAL, TRUE);
  188.     ChkRslt(rslt, "SetProp");
  189.  
  190.     Screen("    Execute the SQL statement...");
  191.     rslt = DbiQExec(hStmt, &hCur);
  192.     if (ChkRslt(rslt, "QExec") != DBIERR_NONE)
  193.     {
  194.         rslt = DbiEndTran(hDb, hTran, xendABORT);
  195.         ChkRslt(rslt, "EndTran");
  196.         rslt = DbiDeleteTable(hDb, szTblName, NULL);
  197.         ChkRslt(rslt, "DeleteTable");
  198.         CloseDbAndExit(&hDb);
  199.         Screen("\r\n*** End of Example ***");
  200.         return;
  201.     }
  202.  
  203.     // Check for a valid cursor.
  204.     if (hCur)
  205.     {
  206.         rslt = DbiOpenTable(hDb, szTblName, NULL, "UPDTIDX", NULL, 0,
  207.                             dbiREADONLY, dbiOPENSHARED, xltFIELD, TRUE, NULL,
  208.                             &hMCur);
  209.         ChkRslt(rslt, "OpenTable");
  210.  
  211.         Screen("    Display the table using the UPDTIDX index...");
  212.         DisplayTable(hMCur, 0);
  213.  
  214.         rslt = DbiGetCursorProps(hCur, &TblProps);
  215.         ChkRslt(rslt, "GetCursorProps");
  216.  
  217.         pRecBuf = (pBYTE)malloc(TblProps.iRecBufSize * sizeof(BYTE));
  218.  
  219.         Screen("\r\n    Get the first record in the result set (set the current"
  220.                " position in the cursor...)");
  221.         rslt = DbiGetNextRecord(hCur, dbiNOLOCK, pRecBuf, NULL);
  222.         ChkRslt(rslt, "GetNextRecord");
  223.  
  224.         rslt = DbiGetField(hCur, 1, pRecBuf, szFirst, &bBlank);
  225.         ChkRslt(rslt, "GetField");
  226.  
  227.         sprintf(szQuery, "UPDATE UPDTCRNT SET FRSTNAME = '%s' WHERE CURRENT OF"
  228.                 " %s", szNewFirst, szCursorName);
  229.  
  230.         Screen("\r\n    Modifying a record in the query result:"
  231.                "\r\n      change the FRSTNAME field from %s to %s....",
  232.                szFirst, szNewFirst);
  233.  
  234.         // Can also use DbiQPrepareExt/DbiQExec/DbiQFree
  235.         rslt = DbiQExecDirect(hDb, qrylangSQL, szQuery, NULL);
  236.         ChkRslt(rslt, "QExecDirect");
  237.  
  238.         Screen("\r\n    Close the cursor...");
  239.         rslt = DbiCloseCursor(&hCur);
  240.         ChkRslt(rslt, "CloseCursor");
  241.  
  242.         Screen("    Commit the changes...");
  243.         rslt = DbiEndTran(hDb, hTran, xendCOMMIT);
  244.         ChkRslt(rslt, "EndTran");
  245.  
  246.         // Refresh the cursor
  247.         Screen("\r\n    Resynch the cursor to the table...");
  248.         rslt = DbiForceReread(hMCur);
  249.         ChkRslt(rslt, "ForceReread");
  250.  
  251.         rslt = DbiSetToBegin(hMCur);
  252.         ChkRslt(rslt, "SetToBegin");
  253.  
  254.         Screen("\r\n    Again, display the table opened using DbiOpenTable");
  255.         Screen("      (Notice that the table reflects the changes made"
  256.                " to the query)");
  257.         DisplayTable(hMCur, 0);
  258.  
  259.         rslt = DbiCloseCursor(&hMCur);
  260.         ChkRslt(rslt, "CloseCursor");
  261.     }
  262.     else
  263.     {
  264.         Screen("        Could not get cursor to the answer set.");
  265.     }
  266.  
  267.     Screen("\r\n    Release memory allocated for the query...");
  268.     rslt = DbiQFree(&hStmt);
  269.     ChkRslt(rslt, "QryFree");
  270.  
  271.     rslt = DbiDeleteTable(hDb, szTblName, NULL);
  272.     ChkRslt(rslt, "DeleteTable");
  273.  
  274.     if (pRecBuf)
  275.     {
  276.         free(pRecBuf);
  277.     }
  278.  
  279.     Screen("    Close the database and exit IDAPI...");
  280.     CloseDbAndExit(&hDb);
  281.  
  282.     Screen("\r\n*** End of Example ***");
  283. }
  284.  
  285. //=====================================================================
  286. //  Function:
  287. //          CreateSQLTable(hDb, pszTblName);
  288. //
  289. //  Input:  phDb        - Pointer to the database handle.
  290. //          pszTblName  - The name of the table to create.
  291. //
  292. //  Return: Result returned by IDAPI.
  293. //
  294. //  Description:
  295. //          This function will create a table and add records to that
  296. //          table.
  297. //=====================================================================
  298. DBIResult
  299. CreateSQLTable (hDBIDb hDb, pCHAR pszTblName)
  300. {
  301.     DBIResult   rslt;           // Value returned from IDAPI functions
  302.     CRTblDesc   crTblDesc;      // Table Descriptor
  303.     hDBICur     hCur;           // Cursor used for adding records
  304.  
  305.     // Initialize the Table Create Descriptor.
  306.     memset(&crTblDesc, 0, sizeof(CRTblDesc));
  307.  
  308.     strcpy(crTblDesc.szTblName, pszTblName);
  309.     crTblDesc.iFldCount     = uNumFields;
  310.     crTblDesc.pfldDesc      = fldDesc;
  311.     crTblDesc.iIdxCount     = 1;
  312.     crTblDesc.pidxDesc      = &IdxDesc;
  313.  
  314.     Screen("    Creating the table...");
  315.     rslt = DbiCreateTable(hDb, TRUE, &crTblDesc);
  316.     if (ChkRslt(rslt, "CreateTable") != DBIERR_NONE)
  317.     {
  318.         return rslt;
  319.     }
  320.  
  321.     rslt = DbiOpenTable(hDb, pszTblName, NULL,
  322.                         NULL, NULL, 0, dbiREADWRITE, dbiOPENEXCL,
  323.                         xltFIELD, TRUE, NULL, &hCur);
  324.     if (ChkRslt(rslt, "OpenTable") != DBIERR_NONE)
  325.     {
  326.         rslt = DbiDeleteTable(hDb, pszTblName, NULL);
  327.         ChkRslt(rslt, "DeleteTable");
  328.         return rslt;
  329.     }
  330.  
  331.     // Add records to the table.
  332.     Screen("    Adding records to the table...");
  333.     AddRecord(hCur, "Tom", "Smith");
  334.     AddRecord(hCur, "Jim", "Jones");
  335.     AddRecord(hCur, "Larry", "Peterson");
  336.     AddRecord(hCur, "Jane", "Jackson");
  337.     AddRecord(hCur, "Mary", "Wong");
  338.  
  339.     rslt = DbiCloseCursor(&hCur);
  340.     ChkRslt(rslt, "CloseTable");
  341.  
  342.     return rslt;
  343. }
  344.  
  345. //=====================================================================
  346. //  Function:
  347. //          AddRecord (hDBICur hCur, pCHAR pFirst, pCHAR pLast)
  348. //
  349. //  Input:  hCur    - The table handle
  350. //          pFirst  - First Name
  351. //          pLast   - Last Name
  352. //
  353. //  Return: Result of adding the record to the table
  354. //
  355. //  Description:
  356. //          Insert a record into the table.
  357. //=====================================================================
  358. DBIResult
  359. AddRecord (hDBICur hCur, pCHAR pFirst, pCHAR pLast)
  360. {
  361.     DBIResult   rslt;       // Return value from IDAPI functions
  362.     pBYTE       pRecBuf;    // Record buffer
  363.     CURProps    TblProps;   // Table properties
  364.  
  365.     // Allocate a record buffer.
  366.     rslt = DbiGetCursorProps(hCur, &TblProps);
  367.     ChkRslt(rslt, "GetCursorProps");
  368.  
  369.     pRecBuf = (pBYTE) malloc(TblProps.iRecBufSize * sizeof(BYTE));
  370.     if (pRecBuf == NULL)
  371.     {
  372.         Screen("    Error - Out of memory");
  373.         return DBIERR_NOMEMORY;
  374.     }
  375.  
  376.     // Clear the record buffer, then add the data.
  377.     rslt = DbiInitRecord(hCur, pRecBuf);
  378.     ChkRslt(rslt, "InitRecord");
  379.  
  380.     rslt = DbiPutField(hCur, 1, pRecBuf, (pBYTE) pFirst);
  381.     ChkRslt(rslt, "PutField");
  382.  
  383.     rslt = DbiPutField(hCur, 2, pRecBuf, (pBYTE) pLast);
  384.     ChkRslt(rslt, "PutField");
  385.  
  386.     rslt = DbiInsertRecord(hCur, dbiNOLOCK, pRecBuf);
  387.     ChkRslt(rslt, "InsertRecord");
  388.  
  389.     free(pRecBuf);
  390.  
  391.     return rslt;
  392. }
  393.  
  394.  
  395.